package cn.bouncyslime.graduationProject.nba.util;

import java.math.BigDecimal;

/**
 * 浮点数精确运算工具类
 *
 * @author 张一卓
 */
public class BigDecimalUtil {

    /**
     * 默认的小数点后保留位数
     */
    public static final int DEFAULT_SCALE = 10;

    private BigDecimalUtil() {

    }

    /**
     * 浮点数精确加法
     *
     * @param value  加数
     * @param value2 加数
     * @return double    两数相加之后的结果
     */
    public static double add(double value, double value2) {
        BigDecimal bigDecimal = BigDecimal.valueOf(value);
        BigDecimal bigDecimal2 = BigDecimal.valueOf(value2);
        return bigDecimal.add(bigDecimal2).doubleValue();
    }

    /**
     * 浮点数精确加法，输入参数为String，而{@link #add(double, double)}输入参数为double型
     *
     * @param value  加数
     * @param value2 加数
     * @return double    两数相加之后的结果
     */
    public static double add(String value, String value2) {
        BigDecimal bigDecimal = new BigDecimal(value);
        BigDecimal bigDecimal2 = new BigDecimal(value2);
        return bigDecimal.add(bigDecimal2).doubleValue();
    }

    /**
     * 浮点数精确减法
     *
     * @param value  被减数
     * @param value2 减数
     * @return double    两数相减之后的结果
     */
    public static double subtract(double value, double value2) {
        BigDecimal bigDecimal = BigDecimal.valueOf(value);
        BigDecimal bigDecimal2 = BigDecimal.valueOf(value2);
        return bigDecimal.subtract(bigDecimal2).doubleValue();
    }

    /**
     * 浮点数精确减法。输入参数为String，而{@link #subtract(double, double)}输入参数为double型
     *
     * @param value  被减数
     * @param value2 减数
     * @return double    两数相减之后的结果
     */
    public static double subtract(String value, String value2) {
        BigDecimal bigDecimal = new BigDecimal(value);
        BigDecimal bigDecimal2 = new BigDecimal(value2);
        return bigDecimal.subtract(bigDecimal2).doubleValue();
    }

    /**
     * 浮点数精确乘法
     *
     * @param value  被乘数
     * @param value2 乘数
     * @return double    两数相乘之后的结果
     */
    public static double multiply(double value, double value2) {
        BigDecimal bigDecimal = BigDecimal.valueOf(value);
        BigDecimal bigDecimal2 = BigDecimal.valueOf(value2);
        return bigDecimal.multiply(bigDecimal2).doubleValue();
    }

    /**
     * 浮点数精确乘法。输入参数为String，而{@link #multiply(double, double)}输入参数为double型
     *
     * @param value  被乘数
     * @param value2 乘数
     * @return double    两数相乘之后的结果
     */
    public static double multiply(String value, String value2) {
        BigDecimal bigDecimal = new BigDecimal(value);
        BigDecimal bigDecimal2 = new BigDecimal(value2);
        return bigDecimal.multiply(bigDecimal2).doubleValue();
    }

    /**
     * 浮点数精确除法，采用默认的小数点保留位数，采用四舍五入的舍入模式
     *
     * @param value  被除数
     * @param value2 除数
     * @return double    两数相除之后的结果
     */
    public static double divide(double value, double value2) {
        return divide(value, value2, DEFAULT_SCALE);
    }

    /**
     * 浮点数精确除法，需要自定义小数点后位数，采用四舍五入的舍入模式
     *
     * @param value  被除数
     * @param value2 除数
     * @param scale  小数点后位数
     * @return double    两数相除之后的结果
     */
    public static double divide(double value, double value2, int scale) {
        BigDecimal bigDecimal = BigDecimal.valueOf(value);
        BigDecimal bigDecimal2 = BigDecimal.valueOf(value2);
        return bigDecimal.divide(bigDecimal2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * 浮点数精确除法，采用默认的小数点后位数，采用四舍五入的舍入模式。输入参数为String，而{@link #divide(double, double)}输入参数为double型
     *
     * @param value  被除数
     * @param value2 除数
     * @return double    两数相除之后的结果
     */
    public static double divide(String value, String value2) {
        return divide(value, value2, DEFAULT_SCALE);
    }

    /**
     * 浮点数精确除法，需要自定义小数点后位数，采用四舍五入的舍入模式。输入参数中参与运算的两数为String，而{@link #divide(double, double, int)}为double型
     *
     * @param value  被除数
     * @param value2 除数
     * @param scale  小数点后位数
     * @return double    两数相除之后的结果
     */
    public static double divide(String value, String value2, int scale) {
        BigDecimal bigDecimal = new BigDecimal(value);
        BigDecimal bigDecimal2 = new BigDecimal(value2);
        return bigDecimal.divide(bigDecimal2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }


    public static BigDecimal div(String value, String value2){
        return div(value, value2, DEFAULT_SCALE);
    }

    public static BigDecimal div(String value, String value2, int scale){
        BigDecimal bigDecimal = new BigDecimal(value);
        BigDecimal bigDecimal2 = new BigDecimal(value2);
        return bigDecimal.divide(bigDecimal2, scale, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 浮点数舍入运算，需要自己指定小数点后的位数
     *
     * @param value 需要进行舍入的数
     * @param scale 小数点后需要保留的位数
     * @return double    舍入之后的结果
     */
    public static double round(double value, int scale) {
        BigDecimal bigDecimal = BigDecimal.valueOf(value);
        BigDecimal bigDecimal2 = BigDecimal.valueOf(1);
        return bigDecimal.divide(bigDecimal2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * 浮点数舍入运算，需要自己指定小数点后的位数。舍入参数为String类型，而@{link {@link #round(double, int)}为double型
     *
     * @param value 需要进行舍入的数
     * @param scale 小数点后需要保留的位数
     * @return double    舍入之后的结果
     */
    public static double round(String value, int scale) {
        BigDecimal bigDecimal = new BigDecimal(value);
        BigDecimal bigDecimal2 = BigDecimal.valueOf(1);
        return bigDecimal.divide(bigDecimal2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }
}